package com.cynteka.cyfoman.ui;

import com.cynteka.cyfoman.core.Util;
import com.cynteka.cyfoman.core.config.Explorer;
import com.cynteka.cyfoman.core.config.ExplorerRowType;
import org.jdesktop.swingx.treetable.FileSystemModel;

import javax.swing.tree.TreePath;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * User: ukman
 * Date: 19.07.2011
 * Time: 11:33:18
 */
public class ExplorerFileSystemModel extends FileSystemModel {

    private Explorer explorer;

    public ExplorerFileSystemModel(Explorer explorer) {
        super(new File(explorer.getBaseFolder()));
        this.explorer = explorer;
    }

    public ExplorerFileSystemModel() {
    }

    public void refresh() {
        File root = getRoot();//, f1 = root.listFiles()[0];
        for (File f : root.listFiles()) {
            this.modelSupport.fireTreeStructureChanged(new TreePath(new Object[]{root, f}));
        }
    }

    @Override
    public int getColumnCount() {
        return (explorer.getColumns() != null ? explorer.getColumns().size() : 0);
    }

    @Override
    public Class<?> getColumnClass(int column) {
        return String.class;
    }

    @Override
    public String getColumnName(int column) {
        return explorer.getColumns().get(column).getTitle();
    }

    @Override
    public Object getValueAt(Object node, int column) {
        File f = (File) node;
        String mask = explorer.getColumns().get(column).getMask();
        String value = "";

        if (mask != null) {
            value = Util.substituteParams(mask, "name", f.getName());
            value = Util.substituteParams(value, "size", f.length());
            RowType rowType = checkRowType(f);
            if (rowType != null) {
                int idx = 1;
                for (String colName : rowType.explorerRowType.getColumnNames()) {
                    String s = rowType.matcher.group(idx);
                    value = Util.substituteParams(value, colName, s);
                    idx++;
                }
            }
            value = Util.substituteAllParams(value, "");
        }
        return value;
    }

    protected static class RowType {
        protected final ExplorerRowType explorerRowType;
        protected final Matcher matcher;

        public RowType(ExplorerRowType explorerRowType, Matcher matcher) {
            this.explorerRowType = explorerRowType;
            this.matcher = matcher;
        }
    }

    private Map<File, RowType> cache = new HashMap<File, RowType>();

    protected RowType checkRowType(File f) {
        RowType rt = null;
        if (cache.containsKey(f)) {
            rt = cache.get(f);
            return rt;
        }
        File baseFolder = new File(explorer.getBaseFolder());
        for (ExplorerRowType rowType : explorer.getRowTypes()) {
            Pattern p = rowType.getPattern();
            String relName = Util.getRelationName(f, baseFolder);
            Matcher m = p.matcher(f.getName());
            if (m.find()) {
                rt = new RowType(rowType, m);
                cache.put(f, rt);
                return rt;
            }
        }
        cache.put(f, rt);
        return rt;
    }
}
